package org.particles.domain.world;

import org.particles.domain.Particle;
import org.particles.domain.Vector2D;

/**
 * OutOfWorldBoundResolver implementation for 2D world. particles
 * will be ricocheted from the worlds bounds.
 */
public class RicochetOutOfBoundResolver implements OutOfWorldBoundResolver {

	/**
	 * @throws NullPointerException if particle is null.
	 * @throws ClassCastException if particle's space place does not
	 * consist of Vector2D or if particle is an AtomParticle
	 * and his impulse does not consist of Vector2D.
	 */
	@Override
	public void resolve(World world, int particleIndex) {
		final Vector2D worldDim = (Vector2D) world.getDimension();
		final Particle particle = world.getParticles().get(particleIndex);
		final Vector2D place = (Vector2D) particle.getSpacePlace();
		final Vector2D impulse = (Vector2D) particle.getImpulse();
		final double min = 0;
		if(place.getX() < min || place.getX() > worldDim.getX()) {
			if(place.getX() < min) {
				place.setX(min);
			}
			else if(place.getX() > worldDim.getX()) {
				place.setX(worldDim.getX());
			}
			// mirror vector by Y axis
			impulse.setX(-impulse.getX());
		}
		if(place.getY() < min || place.getY() > worldDim.getY()) {
			if(place.getY() < min) {
				place.setY(min);
			}
			else if(place.getY() > worldDim.getY()) {
				place.setY(worldDim.getY());
			}
			// mirror vector by X axis
			impulse.setY(-impulse.getY());
		}
	}
}
